package fr.umlv.escapeir.ship;

import java.awt.Image;

import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.FixtureDef;

import fr.umlv.escapeir.GameWorld;
import fr.umlv.escapeir.game.Behavior;
import fr.umlv.escapeir.game.Behaviors;
import fr.umlv.escapeir.painter.AnimatedWorldPainter;
import fr.umlv.escapeir.painter.WorldGraphics2D;
import fr.umlv.escapeir.weapon.FakeWeapon;
import fr.umlv.escapeir.weapon.Weapon;

abstract class PolygonShip implements Ship {

	private final BodyDef bdef;
	private final GameWorld world;
	private final FixtureDef fdef;
	private final Weapon fakeWeapon;

	private Body body;
	private AnimatedWorldPainter painter;
	private Behavior behavior;
	private Weapon weapon;
	

	protected PolygonShip (GameWorld gameWorld, float x, float y, float angle, PolygonShape shape, final Image image, final Vec2 imageTopLeft, final Vec2 imageBottomRight, int groupIndex) {
		bdef = new BodyDef();
		bdef.type = BodyType.DYNAMIC;
		bdef.position.set(x, y);
		bdef.angle = angle;

		world = gameWorld;
		
		fdef = new FixtureDef();
		fdef.restitution = 0;
		fdef.density = 0;
		fdef.shape = shape;
		fdef.filter.groupIndex = groupIndex;
		
		painter = new AnimatedWorldPainter() {
			final Image img = image;
			final Vec2 topLeft = imageTopLeft;
			final Vec2 bottomRight = imageBottomRight;

			public void render(WorldGraphics2D painter) {
				painter.save();
				painter.translateFromWorld(body.getPosition());
				painter.rotate(body.getAngle());
				painter.drawRectWithImage(topLeft, bottomRight, img);
				painter.restore();
			}
			@Override
			public void apply() {}
		};
		fakeWeapon = new FakeWeapon(world);
		weapon = fakeWeapon;
		behavior = Behaviors.INERTIA;
	}

	@Override
	public void render(WorldGraphics2D painter) {
		weapon.render(painter);
		this.painter.render(painter);
	}

	@Override
	public void apply() {
		behavior.apply();
		painter.apply();
		weapon.apply();
	}
	
	@Override
	public Vec2 position () {
		return new Vec2(body.getPosition());
	}
	
	@Override
	public float angle() {
		return body.getAngle();
	}
	
	@Override
	public GameWorld world() {
		return world;
	}
	
	@Override
	public void fire(float theta) {
		getWeapon().fire(theta);
		resetWeapon();
	}
	
	protected Body getBody() {
		return body;
	}

	protected void setBody(Body body) {
		this.body = body;
	}

	protected AnimatedWorldPainter getPainter() {
		return painter;
	}

	protected void setPainter(AnimatedWorldPainter painter) {
		this.painter = painter;
	}

	protected Behavior getBehavior() {
		return behavior;
	}

	void setBehavior(Behavior behavior) {
		this.behavior = behavior;
	}

	protected BodyDef getBdef() {
		return bdef;
	}

	protected GameWorld getWorld() {
		return world;
	}

	protected FixtureDef getFdef() {
		return fdef;
	}
	
	protected void setWeapon (Weapon weapon) {
		this.weapon = weapon;
	}
	
	protected Weapon getWeapon () {
		return weapon;
	}
	
	protected void resetWeapon() {
		weapon = fakeWeapon;
	}

}